#!/usr/bin/env node

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import axios from 'axios';

class FigmaMCPServer {
  constructor() {
    this.server = new Server(
      {
        name: 'figma-mcp-server',
        version: '1.0.0',
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    this.figmaToken = process.env.FIGMA_ACCESS_TOKEN;
    this.setupToolHandlers();
  }

  setupToolHandlers() {
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        {
          name: 'get_figma_file',
          description: 'Get Figma file data by file ID',
          inputSchema: {
            type: 'object',
            properties: {
              fileId: {
                type: 'string',
                description: 'Figma file ID',
              },
            },
            required: ['fileId'],
          },
        },
        {
          name: 'get_figma_node',
          description: 'Get specific node from Figma file',
          inputSchema: {
            type: 'object',
            properties: {
              fileId: {
                type: 'string',
                description: 'Figma file ID',
              },
              nodeId: {
                type: 'string',
                description: 'Node ID to retrieve',
              },
            },
            required: ['fileId', 'nodeId'],
          },
        },
      ],
    }));

    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;

      if (!this.figmaToken) {
        throw new Error('FIGMA_ACCESS_TOKEN environment variable is required');
      }

      switch (name) {
        case 'get_figma_file':
          return await this.getFigmaFile(args.fileId);
        case 'get_figma_node':
          return await this.getFigmaNode(args.fileId, args.nodeId);
        default:
          throw new Error(`Unknown tool: ${name}`);
      }
    });
  }

  async getFigmaFile(fileId) {
    try {
      const response = await axios.get(`https://api.figma.com/v1/files/${fileId}`, {
        headers: {
          'X-Figma-Token': this.figmaToken,
        },
      });

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data, null, 2),
          },
        ],
      };
    } catch (error) {
      throw new Error(`Failed to fetch Figma file: ${error.message}`);
    }
  }

  async getFigmaNode(fileId, nodeId) {
    try {
      const response = await axios.get(`https://api.figma.com/v1/files/${fileId}/nodes`, {
        headers: {
          'X-Figma-Token': this.figmaToken,
        },
        params: {
          ids: nodeId,
        },
      });

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data, null, 2),
          },
        ],
      };
    } catch (error) {
      throw new Error(`Failed to fetch Figma node: ${error.message}`);
    }
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('Figma MCP server running on stdio');
  }
}

const server = new FigmaMCPServer();
server.run().catch(console.error);
